Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Xml
Imports System.Collections.Generic

Imports System.Security.Cryptography
Imports System.web.Configuration

Imports DnnPerm = DotNetNuke.Security.Permissions
Imports DnnRoles = DotNetNuke.Security.Roles
Imports DnnFS = DotNetNuke.Services.FileSystem


Namespace DotNetNuke.Modules.IWeb

    <Script.Services.ScriptService()> _
    <Serialization.XmlInclude(GetType(DotNetNuke.Services.FileSystem.FileInfo))> _
    <Serialization.XmlInclude(GetType(DotNetNuke.Services.FileSystem.FolderInfo))> _
     Partial Public Class WebService

#Region "Info Classes"

        <Serializable()> _
        Public Class IWebFileInfo
            Private info As New DnnFS.FileInfo
            Private lastModifiedField As Date = Now


            Public Sub New()

            End Sub

            Public Sub New(ByVal folderId As Integer, ByVal fileId As Integer, ByVal fileName As String)

                Me.info.FolderId = folderId
                Me.info.FileId = fileId
                Me.info.FileName = fileName


            End Sub

            Public Sub New(ByVal info As DnnFS.FileInfo)
                Me.info = info

                Me.LastModified = IO.File.GetLastWriteTime(Me.info.PhysicalPath)


            End Sub


            '''<remarks/>
            Public Property ContentType() As String
                Get
                    Return Me.info.ContentType
                End Get
                Set(ByVal value As String)
                    Me.info.ContentType = value
                End Set
            End Property


            '''<remarks/>
            Public Property Extension() As String
                Get
                    Return Me.info.Extension
                End Get
                Set(ByVal value As String)
                    Me.info.Extension = value
                End Set
            End Property

            Property LastModified() As Date
                Get
                    Return Me.lastModifiedField
                End Get
                Set(ByVal value As Date)
                    Me.lastModifiedField = value
                End Set
            End Property


            '''<remarks/>
            Public Property FileId() As Integer
                Get
                    Return Me.info.FileId
                End Get
                Set(ByVal value As Integer)
                    Me.info.FileId = value
                End Set
            End Property

            '''<remarks/>
            Public Property FileName() As String
                Get
                    Return Me.info.FileName
                End Get
                Set(ByVal value As String)
                    Me.info.FileName = value
                End Set
            End Property

            '''<remarks/>
            Public Property FolderId() As Integer
                Get
                    Return Me.info.FolderId
                End Get
                Set(ByVal value As Integer)
                    Me.info.FolderId = value
                End Set
            End Property


            '''<remarks/>
            Public Property Height() As Integer
                Get
                    Return Me.info.Height
                End Get
                Set(ByVal value As Integer)
                    Me.info.Height = value
                End Set
            End Property

            '''<remarks/>
            Public Property Size() As Integer
                Get
                    Return Me.info.Size
                End Get
                Set(ByVal value As Integer)
                    Me.info.Size = value
                End Set
            End Property

            '''<remarks/>
            Public Property Width() As Integer
                Get
                    Return Me.info.Width
                End Get
                Set(ByVal value As Integer)
                    Me.info.Width = value
                End Set
            End Property




        End Class


        <Serializable()> _
        Public Class IWebFolderInfo
            Private info As New DnnFS.FolderInfo

            Private folderNameField As String = String.Empty


            Public Sub New()

            End Sub

            Public Sub New(ByVal id As Integer, ByVal name As String)
                Me.info.FolderID = id
                Me.folderNameField = name

            End Sub

            Public Sub New(ByVal info As DnnFS.FolderInfo)
                Me.info = info

            End Sub


            Public Property FolderId() As Integer
                Get
                    Return Me.info.FolderID
                End Get
                Set(ByVal value As Integer)
                    Me.info.FolderID = value
                End Set
            End Property

            Public Shadows Property FolderName() As String
                Get
                    Return folderNameField
                End Get
                Set(ByVal value As String)
                    Me.folderNameField = value
                End Set
            End Property



        End Class

#End Region


#Region "Consts"

        Private Const Pattern_TotalSpaceUsed As String = "Using: {0}"
        Private Const Pattern_TotalSpaceUsedWithQuota As String = "Used: {0} of {1}"

        Private Const Setting_MaxRetries As Integer = 3000
        Private Const Setting_MaxSeconds As Integer = 10

        Private Const RegEx_FolderNameWithParents As String = "^[a-zA-Z0-9\-\s_\/]{1,250}$"
        Private Const RegEx_FolderNameWithOutParents As String = "^[a-zA-Z0-9\-\s_]{1,250}$"
        Private Const RegEx_FileNameWithFolders As String = "^[a-zA-Z0-9\-\s_./]{1,250}$"
        Private Const RegEx_FileNameWithOutFolders As String = "^[a-zA-Z0-9\-\s_.]{1,250}$"


        Private Const Permission_ReadId As Integer = 5
        Private Const Permission_WriteId As Integer = 6
        Private ReadOnly FileManager_QName As New XmlQualifiedName("FileManager")

#End Region


#Region "Private Methods"


        Private Shared Function ConvertToGenericListOfFolderInfo(ByVal folderArray As ArrayList) As List(Of IWebFolderInfo)

            Dim folderList As New List(Of IWebFolderInfo)

            Try


                For Each folder As DnnFS.FolderInfo In folderArray

                    folderList.Add(New IWebFolderInfo(folder.FolderID, folder.FolderName))

                Next

            Catch castEx As InvalidCastException

                Return Nothing

            Catch ex As Exception

                Return Nothing

            End Try

            Return folderList

        End Function

        Private Shared Function ConvertToGenericListOfFileInfo(ByVal fileArray As ArrayList) As List(Of IWebFileInfo)

            Dim fileList As New List(Of IWebFileInfo)

            Try


                For Each file As DnnFS.FileInfo In fileArray

                    fileList.Add(New IWebFileInfo(file))

                Next

            Catch castEx As InvalidCastException

                Return Nothing

            Catch ex As Exception

                Return Nothing

            End Try

            Return fileList

        End Function


        Private Shared Function ConvertToMB(ByVal bytes As Integer) As Long

            Return CLng((bytes / (1024 * 1024)))

        End Function

        Private Shared Function GetSettings() As Entities.Portals.PortalSettings

            Return PortalController.GetCurrentPortalSettings

        End Function

        Private Function CleanErrorMessage(ByVal strErrorMessage As String) As String
            Dim cleanedError As String

            cleanedError = strErrorMessage.Replace _
                (Server.MapPath("~/Portals/" & Me.IWebCredentials.PortalID.ToString), String.Empty)

            Return cleanedError

        End Function

        Private Function CleanPath(ByVal rawPath As String) As String

            If String.IsNullOrEmpty(rawPath) Then Return String.Empty

            Return Regex.Replace(rawPath, "[.]{2,}", String.Empty)

        End Function

        Private Function IsFilePath(ByVal rawPath As String, ByVal allowFolders As Boolean) As Boolean

            Dim pattern As String = String.Empty

            If allowFolders Then

                pattern = RegEx_FileNameWithFolders

            Else

                pattern = RegEx_FileNameWithOutFolders

            End If

            If RegularExpressions.Regex.IsMatch(rawPath, pattern, _
                RegexOptions.Compiled Or RegexOptions.IgnoreCase) Then

                Return True

            End If


            Return False



        End Function

        Private Function IsFolderPath(ByVal rawPath As String, ByVal allowParents As Boolean) As Boolean

            If String.IsNullOrEmpty(rawPath) Then Return True

            Dim pattern As String

            If allowParents Then
                pattern = RegEx_FolderNameWithParents

            Else
                pattern = RegEx_FolderNameWithOutParents

            End If


            If RegularExpressions.Regex.IsMatch(rawPath, pattern, _
                RegexOptions.Compiled Or RegexOptions.IgnoreCase) Then

                Return True

            End If


            Return False

        End Function


        Private Function GetRelativeFilePath(ByVal fileId As Integer) As String

            Dim fileController As New DnnFS.FileController

            Dim file As DnnFS.FileInfo = fileController.GetFileById(fileId, Me.IWebCredentials.PortalID)

            Return IO.Path.Combine(file.Folder, file.FileName)

        End Function

        Private Function GetRelativeFilePath(ByVal folderId As Integer, ByVal fileName As String) As String

            Dim cleanFileName As String = IO.Path.GetFileName(Me.CleanPath(fileName))

            Return IO.Path.Combine(Me.GetRelativeFolderPath(folderId), cleanFileName)

        End Function

        Private Function GetFileMapPath(ByVal fileId As Integer) As String

            Dim info As IWebFileInfo = Me.GetFileById(fileId)

            Return Me.GetFileMapPath(info.FolderId, info.FileName)

        End Function

        Private Function GetFileMapPath(ByVal folderId As Integer, ByVal fileName As String) As String

            Return Server.MapPath(GetSettings.HomeDirectory & Me.GetRelativeFilePath(folderId, fileName))

        End Function

        Private Function GetHomeDirectoryFolderId() As Integer


            Dim folderController As New DnnFS.FolderController()

            Dim folder As DnnFS.FolderInfo = FileSystemUtils.GetFolder _
                (Me.IWebCredentials.PortalID, String.Empty)

            If folder IsNot Nothing Then

                Return folder.FolderID

            Else

                Return -1

            End If


        End Function

        Private Function GetRelativeFolderPath(ByVal folderId As Integer) As String

            Dim folderControl As New DnnFS.FolderController

            If folderId < 1 Then

                Return String.Empty

            End If

            Dim folder As DotNetNuke.Services.FileSystem.FolderInfo

            folder = folderControl.GetFolderInfo(Me.IWebCredentials.PortalID, folderId)

            If folder IsNot Nothing Then

                Return folder.FolderPath

            Else

                Return String.Empty

            End If


        End Function

        Private Function GetFolderMapPath(ByVal folderId As Integer) As String

            Dim relativePath As String = Me.GetRelativeFolderPath(folderId)

            If Not String.IsNullOrEmpty(relativePath) Then

                Return Server.MapPath(GetSettings.HomeDirectory & relativePath)

            Else

                Return GetSettings.HomeDirectoryMapPath

            End If

        End Function


        Private Function GetLoggedNotAuthorizedEx() As SoapException

            Dim dnnEx As New System.Security.SecurityException _
                ("Not Authorized to preform this function: " & My.Request.RawUrl & _
                 " Username: " & Me.IWebCredentials.Username)


            Exceptions.LogException(dnnEx)


            Dim soapEx As SoapException = New SoapException _
                ("Not Authorized to preform this function. Username: " & _
                Me.IWebCredentials.Username, FileManager_QName)

            Return soapEx

        End Function


        Private Function HasFileAccess(ByVal fileId As Integer, ByVal permissionType As Integer) As Boolean


            Dim fileController As New DnnFS.FileController

            Dim file As DnnFS.FileInfo = fileController.GetFileById(fileId, Me.IWebCredentials.PortalID)

            Return Me.HasFolderAccess(file.FolderId, permissionType)

        End Function

        Private Function HasFolderAccess(ByVal folderId As Integer, ByVal permissionType As Integer) As Boolean


            Dim user As UserInfo = UserController.GetUserByName _
                (Me.IWebCredentials.PortalID, Me.IWebCredentials.Username, False)

            Me.IWebCredentials.UserID = user.UserID

            If user.IsSuperUser Then Return True

            Dim roleCtrl As New DnnRoles.RoleController

            user.Roles = roleCtrl.GetRolesByUser(user.UserID, Me.IWebCredentials.PortalID)

            Dim ctrl As New DnnPerm.FolderPermissionController

            Dim folderPermsList As DnnPerm.FolderPermissionCollection

            folderPermsList = ctrl.GetFolderPermissionsCollectionByFolderPath _
                (Me.IWebCredentials.PortalID, Me.GetRelativeFolderPath(folderId))

            Dim allowed As Boolean = False

            For Each perm As DnnPerm.FolderPermissionInfo In folderPermsList


                If perm.AllowAccess AndAlso perm.PermissionID = permissionType _
                    AndAlso (perm.UserID = Me.IWebCredentials.UserID _
                    OrElse user.IsInRole(perm.RoleName)) Then

                    allowed = True

                ElseIf Not perm.AllowAccess AndAlso perm.PermissionID = permissionType _
                    AndAlso (perm.UserID = Me.IWebCredentials.UserID _
                    OrElse user.IsInRole(perm.RoleName)) Then

                    allowed = False
                    Exit For

                End If

            Next

            Return allowed

        End Function


        Private Sub SetHeader(ByVal PortalID As Integer, _
        ByVal UserID As Integer, ByVal Username As String, ByVal Password As String, ByVal ModuleId As String, _
        ByVal WebPageCall As Boolean, ByVal Encrypted As Boolean)

            Me.IWebCredentials = New IWebAuthendicationHeader

            Me.IWebCredentials.PortalID = PortalID
            Me.IWebCredentials.UserID = UserID
            Me.IWebCredentials.Username = Username
            Me.IWebCredentials.Password = Password
            Me.IWebCredentials.ModuleId = ModuleId            
            Me.IWebCredentials.WebPageCall = WebPageCall
            Me.IWebCredentials.Encrypted = Encrypted

        End Sub

        Private Sub SyncFilesSystem()

            FileSystemUtils.SynchronizeFolder(Me.IWebCredentials.PortalID, _
                                GetSettings.HomeDirectoryMapPath, String.Empty, True)
        End Sub

#End Region


#Region "Web Methods"

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="AddFolderAjax", _
        Description:="Add a new folder to specified parent or portal root. Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! ")> _
        Public Sub AddFolderAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, _
            ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal parentFolderId As Integer, ByVal newFolderName As String)

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Me.AddFolder(parentFolderId, newFolderName)

        End Sub
        <WebMethod(Description:="Add a new folder to specified parent or portal root. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Sub AddFolder(ByVal folderId As Integer, ByVal newFolderName As String)


            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() AndAlso _
                Me.HasFolderAccess(folderId, Permission_WriteId) Then


                Dim parentFolder As String = Me.GetFolderMapPath(folderId)


                Try

                    FileSystemUtils.AddFolder(GetSettings, parentFolder, newFolderName)

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try

            Else


                Throw Me.GetLoggedNotAuthorizedEx()

            End If

        End Sub

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="CopyFileAjax", _
        Description:="Copies a file to a new file with the specified name. Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function CopyFileAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal sourceFileID As Integer, ByVal destFolderId As Integer, ByVal destFileName As String) As String
            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return CopyFile(sourceFileID, destFolderId, destFileName)
        End Function
        <WebMethod(Description:="Copies a file to a new file with the specified name. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function CopyFile(ByVal sourceFileID As Integer, _
            ByVal destFolderId As Integer, ByVal destFileName As String) As String

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFileAccess(sourceFileID, Permission_ReadId) _
                AndAlso Me.HasFolderAccess(destFolderId, Permission_WriteId) Then

                Dim sourceFile As String = Me.GetRelativeFilePath(sourceFileID)

                destFileName = Me.GetRelativeFilePath(destFolderId, destFileName)

                Try

                    Return FileSystemUtils.CopyFile(sourceFile, destFileName, GetSettings)

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try


            Else
                Throw Me.GetLoggedNotAuthorizedEx


            End If

        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="DefaultProtectedFoldersAjax", _
        Description:="Determines if specified path is the default protected folder. Ajax Overload. *DotNetNuke* |IWeb Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DefaultProtectedFoldersAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal folderId As Integer) As Boolean

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)


            Return DefaultProtectedFolders(folderId)
        End Function
        <WebMethod(Description:="Determines if specified path is the default protected folder. *DotNetNuke* |IWeb Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DefaultProtectedFolders(ByVal folderId As Integer) As Boolean

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(folderId, Permission_ReadId) Then


                Try

                    Dim folderPath As String = Me.GetRelativeFolderPath(folderId)


                    Return FileSystemUtils.DefaultProtectedFolders(folderPath)

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try

            Else


                Throw Me.GetLoggedNotAuthorizedEx()

            End If


        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="DeleteFilesAjax", _
        Description:=" Delete the list of specified files. Ajax Overload.  *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DeleteFilesAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal files() As Integer) As String
            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return DeleteFiles(files)
        End Function
        <WebMethod(Description:=" Delete the list of specified files *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DeleteFiles(ByVal files() As Integer) As String

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If Not authendication.ValidAndAuthorized() Then

                Throw Me.GetLoggedNotAuthorizedEx

            End If


            Dim strErrorMessage As String = String.Empty

            Try

                Dim i As Integer
                If files.Length = 0 Then

                    Return "0"

                    Exit Function
                End If

                Dim strCurError As String = String.Empty

                For i = 0 To files.Length - 1

                    Dim timedOut As Boolean = False

                    If Me.HasFileAccess(files(i), Permission_WriteId) Then

                        Dim deleted As Boolean = False

                        Dim startTime As DateTime = Now


                        Do Until deleted OrElse timedOut


                            Try

                                FileSystemUtils.DeleteFile(Me.GetRelativeFilePath(files(i)), GetSettings)

                                IO.File.Delete(Me.GetFileMapPath(files(i)))

                                deleted = True


                            Catch ex As Exception

                                deleted = False

                                timedOut = DateAdd(DateInterval.Second, Setting_MaxSeconds, startTime) < Now

                                If timedOut Then

                                    strCurError &= ex.Message & vbCrLf

                                    Exit Do

                                End If

                            End Try

                        Loop

                    Else

                        strCurError = "Access denied. Please check file permissions and try again."

                    End If

                    If Not String.IsNullOrEmpty(strCurError) OrElse timedOut Then

                        strErrorMessage &= " Error Deleting File: " & strCurError

                    End If

                Next


                Me.SyncFilesSystem()


            Catch ex As Exception

                Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

            End Try

            If Not String.IsNullOrEmpty(strErrorMessage) Then


                Throw New SoapException(CleanErrorMessage(strErrorMessage), FileManager_QName)

            End If

            Return files.Length.ToString

        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="DownloadFileAjax", _
        Description:="Download the specified file.  Ajax Overload. *DotNetNuke* |IWeb Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DownloadFileAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal fileId As Integer) As Byte()


            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return DownloadFile(fileId)
        End Function
        <WebMethod(Description:="Download the specified file. *DotNetNuke* |IWeb Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function DownloadFile(ByVal fileId As Integer) As Byte()

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFileAccess(fileId, Permission_ReadId) Then

                Dim fileLocInfo As DotNetNuke.Services.FileSystem.FileInfo

                Dim fileCtrl As New Services.FileSystem.FileController()

                Dim info As IWebFileInfo = Me.GetFileById(fileId)

                fileLocInfo = fileCtrl.GetFile(IO.Path.GetFileName(info.FileName), _
                    Me.IWebCredentials.PortalID, info.FolderId)

                Return FileSystemUtils.GetFileContent(fileLocInfo)

            Else

                Throw New SoapException("Not Authorized to preform this function", FileManager_QName)

            End If

        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="GetFilesByFolderAjax", _
        Description:=" Get a list of files in the folder supplied.  Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFilesByFolderAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal folderId As Integer) As List(Of IWebFileInfo)

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetFilesByFolder(folderId)
        End Function
        <WebMethod(Description:=" Get a list of files in the folder supplied. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFilesByFolder(ByVal folderId As Integer) As List(Of IWebFileInfo)

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(folderId, Permission_ReadId) Then


                Try

                    Dim files As New List(Of IWebFileInfo)


                    If folderId < 1 Then folderId = Me.GetHomeDirectoryFolderId

                    files = ConvertToGenericListOfFileInfo _
                        (FileSystemUtils.GetFilesByFolder(Me.IWebCredentials.PortalID, folderId))

                    Return files

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try

            Else

                Throw Me.GetLoggedNotAuthorizedEx


            End If


        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(MessageName:="GetFileByIdAjax", _
        Description:=" Get a FileInfo object for the specified FileId.  Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFileByIdAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal fileId As Integer) As IWebFileInfo

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetFileById(fileId)
        End Function
        <WebMethod(Description:=" Get a FileInfo object for the specified FileId. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
         Public Function GetFileById(ByVal fileId As Integer) As IWebFileInfo


            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFileAccess(fileId, Permission_ReadId) Then


                Dim fileController As New DnnFS.FileController

                Dim file As DnnFS.FileInfo = fileController.GetFileById(fileId, Me.IWebCredentials.PortalID)

                Return New IWebFileInfo(file)

            Else

                Throw Me.GetLoggedNotAuthorizedEx

            End If


        End Function

        <System.Web.Script.Services.ScriptMethod()> _
        <WebMethod(Description:=" Get sub folders by parent FolderId.  Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFoldersByParentAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal parentFolderId As Integer) As List(Of IWebFolderInfo)

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetFoldersByParent(parentFolderId)

        End Function
        <WebMethod(Description:=" Get sub folders by parent FolderId. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFoldersByParent(ByVal parentFolderId As Integer) As List(Of IWebFolderInfo)

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(parentFolderId, Permission_ReadId) Then



                Try

                    Dim parentFolder As String = Me.GetRelativeFolderPath(parentFolderId)

                    Return ConvertToGenericListOfFolderInfo _
                        (FileSystemUtils.GetFoldersByParentFolder _
                        (Me.IWebCredentials.PortalID, parentFolder))

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try

            Else

                Throw Me.GetLoggedNotAuthorizedEx()


            End If


        End Function

        <System.Web.Script.Services.ScriptMethod()> _
        <WebMethod(Description:=" Get a FolderInfo object for the specified FolderId. Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFolderByIdAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal folderId As Integer) As IWebFolderInfo
            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetFolderById(folderId)
        End Function
        <WebMethod(Description:=" Get a FolderInfo object for the specified FolderId. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetFolderById(ByVal folderId As Integer) As IWebFolderInfo

            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(folderId, Permission_ReadId) Then


                Dim folderController As New DnnFS.FolderController

                Dim folder As DnnFS.FolderInfo = folderController _
                    .GetFolderInfo(folderId, Me.IWebCredentials.PortalID)

                Return New IWebFolderInfo(folder)

            Else

                Throw New SoapException("Not Authorized to preform this function", FileManager_QName)

            End If

        End Function

        <System.Web.Script.Services.ScriptMethod()> _
        <WebMethod(Description:=" Gets the maximum request length in KBs. Return -1 if configuration could not be read. Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
     Public Function GetMaxRequestLengthAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean) As Long

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)
     
            Return Me.GetMaxRequestLength

        End Function
        <WebMethod(Description:=" Gets the maximum request length in KBs. Return -1 if configuration could not be read. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetMaxRequestLength() As Long


            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(Me.GetHomeDirectoryFolderId, Permission_ReadId) Then

                Try

                    Dim config As System.Configuration.Configuration = _
                       WebConfigurationManager.OpenWebConfiguration("~/DesktopModules/IWeb/Web.config")

                    If config Is Nothing Then Return -1

                    Dim reuntimeSection As HttpRuntimeSection

                    reuntimeSection = TryCast(config.GetSection("system.web/httpRuntime"), HttpRuntimeSection)

                    If reuntimeSection Is Nothing Then Return -1


                    Return reuntimeSection.MaxRequestLength


                Catch ex As Exception

                    Return -1

                End Try

            Else

                Throw Me.GetLoggedNotAuthorizedEx

            End If

        End Function

        <System.Web.Script.Services.ScriptMethod()> _
        <WebMethod(Description:=" Get portal root folders.  Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetPortalRootFoldersAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean) As List(Of IWebFolderInfo)

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetPortalRootFolders()

        End Function
        <WebMethod(Description:=" Get portal root folders. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetPortalRootFolders() As List(Of IWebFolderInfo)


            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() _
                AndAlso Me.HasFolderAccess(Me.GetHomeDirectoryFolderId, Permission_ReadId) Then

                Try

                    Return ConvertToGenericListOfFolderInfo _
                        (FileSystemUtils.GetFolders(Me.IWebCredentials.PortalID))

                Catch ex As Exception

                    Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName, ex)

                End Try

            Else

                Throw Me.GetLoggedNotAuthorizedEx

            End If

        End Function

        <System.Web.Script.Services.ScriptMethod(), _
        WebMethod(Description:=" Get the total space used by the portal folder.  Ajax Overload. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetPortalSpaceUsedAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal showQuota As Boolean) As String

            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return GetPortalSpaceUsed(showQuota)
        End Function
        <WebMethod(Description:=" Get the total space used by the portal folder. *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function GetPortalSpaceUsed(ByVal showQuota As Boolean) As String


            Dim authendication As New IWebAuthendication(Me.IWebCredentials)

            If authendication.ValidAndAuthorized() Then

                Dim strUsed As String

                Dim portalCtrl As New PortalController


                Dim spaceUsed As Long = portalCtrl.GetPortalSpaceUsedBytes _
                    (Me.IWebCredentials.PortalID)

                If spaceUsed < 1024 Then
                    strUsed = spaceUsed.ToString("0.00") + "B"
                ElseIf spaceUsed < (1024 * 1024) Then
                    strUsed = (spaceUsed / 1024).ToString("0.00") + "KB"
                Else
                    strUsed = (ConvertToMB(spaceUsed)).ToString("0.00") + "MB"
                End If

                If showQuota Then


                    Dim hostingSpace As String

                    Dim hostingSpaceMB As Integer = GetSettings.HostSpace

                    If hostingSpaceMB > 0 Then

                        hostingSpace = String.Format("{0}MB", hostingSpaceMB)

                    Else

                        hostingSpace = "[unlimited]"

                    End If


                    Return String.Format(Pattern_TotalSpaceUsedWithQuota, strUsed, hostingSpace)


                Else

                    Return String.Format(Pattern_TotalSpaceUsed, strUsed)

                End If


            Else

                Throw Me.GetLoggedNotAuthorizedEx
            End If

        End Function

        <System.Web.Script.Services.ScriptMethod()> _
        <WebMethod(Description:=" Upload as file. Ajax Overload.  *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function UploadFileAjax(ByVal portalid As Integer, ByVal userId As Integer, ByVal username As String, ByVal password As String, ByVal moduleId As Integer, ByVal webPageCall As Boolean, ByVal encrypted As Boolean, ByVal folderId As Integer, ByVal fileName As String, ByVal bytes As Byte()) As String
            Me.SetHeader(portalid, userId, username, password, moduleId, webPageCall, encrypted)

            Return UploadFile(folderId, fileName, bytes)
        End Function

        <WebMethod(Description:=" Upload as file *DotNetNuke* |IWEB Core| #IWEB FileManager# !Portal! "), SoapHeader("IWebCredentials")> _
        Public Function UploadFile(ByVal folderId As Integer, ByVal fileName As String, ByVal bytes() As Byte) As String


            Dim portalCtrl As New PortalController

            Dim spaceUsed As Long = portalCtrl.GetPortalSpaceUsedBytes _
                (Me.IWebCredentials.PortalID)

            Dim spaceUsedWithFile As Long = _
                CLng((ConvertToMB(spaceUsed) + ConvertToMB(ConvertToMB(bytes.Length)).ToString("0.00")))


            Dim hostingSpace As Long = CLng(GetSettings.HostSpace)

            If hostingSpace = 0 OrElse spaceUsedWithFile < hostingSpace Then

                Dim authendication As New IWebAuthendication(Me.IWebCredentials)

                If authendication.ValidAndAuthorized() _
                    AndAlso Me.HasFolderAccess(folderId, Permission_WriteId) Then

                    Try

                        Dim destFilePath As String

                        destFilePath = Me.GetFileMapPath(folderId, fileName)


                        Dim newFileWriter As IO.FileStream = Nothing

                        Try

                            newFileWriter = New IO.FileStream _
                                (destFilePath, IO.FileMode.OpenOrCreate, IO.FileAccess.Write)

                            newFileWriter.Write(bytes, 0, bytes.Length)


                        Catch ex As Exception

                            Exceptions.LogException(ex)

                            Throw New SoapException("Error uploading " & fileName & ". " & _
                                "Please check your site logs for details.", _
                                FileManager_QName)

                        Finally

                            If newFileWriter IsNot Nothing Then


                                newFileWriter.Flush()

                                newFileWriter.Close()

                                newFileWriter.Dispose()

                                newFileWriter = Nothing

                                bytes = Nothing

                            End If
                        End Try

                        Me.SyncFilesSystem()

                        Return Me.GetPortalSpaceUsed(True)

                    Catch soapEx As SoapException

                        Throw

                    Catch ex As Exception

                        Exceptions.LogException(ex)

                        Throw New SoapException(CleanErrorMessage(ex.Message), FileManager_QName)

                    End Try


                Else

                    Throw Me.GetLoggedNotAuthorizedEx()

                End If



            Else

                Dim soapEx As SoapException = New SoapException _
                    ("Portal disk space quota has been reached, upload has been cancelled. " & _
                    Me.GetPortalSpaceUsed(True), FileManager_QName)

                Exceptions.LogException(soapEx)

                Throw soapEx

            End If

        End Function

#End Region


    End Class

End Namespace